package vns.client.view;

import java.util.ArrayList;
import java.util.List;

import vns.client.helper.Helper;
import vns.client.presenter.ObjectTypeDetailPresenter;
import vns.shared.ObjectPropertyDTO;
import vns.shared.ObjectPropertyTypeDTO;
import vns.shared.ObjectTypeDTO;

import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTMLTable;
import com.google.gwt.user.client.ui.HasText;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HTMLPanel;

public class ObjectTypeDetailUI extends Composite implements ObjectTypeDetailPresenter.Display{
	
	// moi doi ten
	private List<String> listStringColumn = new ArrayList<String>();
	private static int rowSelectedID;
	private List<ObjectPropertyDTO> listRow = new ArrayList<ObjectPropertyDTO>();
	private List<ObjectPropertyTypeDTO> listPType = new ArrayList<ObjectPropertyTypeDTO>();
	private ObjectTypeDTO currentObjectTypeDTO;
	
	private static ObjectTypeDetailUiBinder uiBinder = GWT
			.create(ObjectTypeDetailUiBinder.class);
	@UiField FlexTable flexTable;
	@UiField Button btAdd;
	@UiField Button btDel;
	@UiField Button btUpdate;
	@UiField Button btUp;
	@UiField Button btDown;

	interface ObjectTypeDetailUiBinder extends
			UiBinder<Widget, ObjectTypeDetailUI> {
	}

	public ObjectTypeDetailUI() {
		initWidget(uiBinder.createAndBindUi(this));
		bind();
	}

	private void bind() {
		/*
		 * Tên các cột
		 */
		listStringColumn.add(""); 					// weight		0
		listStringColumn.add("Tên thuộc tính");		// name			1
		listStringColumn.add("Kiểu");				// ptype		2
		listStringColumn.add("TT bắt buộc");		// isRequire	3
		listStringColumn.add("TT tóm tắt");			// isSumary		4
		listStringColumn.add("TT danh sách");		// isList		5
		listStringColumn.add("TT chính");			// isMain		6
		listStringColumn.add("Có nhiều GT");		// isMulti		7
		listStringColumn.add("TT chỉ đọc");			// isReadonly	8
		listStringColumn.add("TT Liên kết");		// isLinked		9
		listStringColumn.add("Mô tả");				// des			10

		flexTable.setBorderWidth(1);
		flexTable.setCellPadding(2);
		flexTable.setCellSpacing(0);

		/*
		 * FlexTable Even
		 */
		flexTable.addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				getClickedRow(event);

			}
		});
		
	}
	/***************************************************************************/
	public void renderClickedRow() {
		if (rowSelectedID > 0) {
			HTMLTable.RowFormatter rf = flexTable.getRowFormatter();
			rf.addStyleName(rowSelectedID, "vnsClickedRow");
		}
	}

	public void unrenderClickedRow() {
		if (rowSelectedID > 0) {
			HTMLTable.RowFormatter rf = flexTable.getRowFormatter();
			rf.removeStyleName(rowSelectedID, "vnsClickedRow");
		}
	}

	public int getClickedRow(ClickEvent event) {
		int selectedRow = -1;
		HTMLTable.Cell cell = flexTable
				.getCellForEvent(event);

		if (cell != null) {
			if (cell.getCellIndex() >= 0) {
				selectedRow = cell.getRowIndex();
				swapClickedRow(selectedRow, cell.getCellIndex());
			}
		}
		
		return selectedRow;
	}

	private void swapClickedRow(int rowNow, int cellindex) {
		if (rowNow != rowSelectedID && rowNow>0) {
			unrenderClickedRow();
			setRowEnable(rowSelectedID, false);
			rowSelectedID = rowNow;
			
			renderClickedRow();
			setRowEnable(rowSelectedID, true);
//			Window.alert("HÃ ng chá»�n bÃ¢y giá»�: "
//					+ Integer.toString(rowSelectedID));
		} else if(rowNow == rowSelectedID && rowNow > 0){
			if(cellindex==0){
				unrenderClickedRow();
				setRowEnable(rowSelectedID, false);
				rowSelectedID = -1;
			}
		}
	}

	/*
	 * Set Row Enable
	 */
	private void setRowEnable(int row, boolean value) {
		if (row <= flexTable.getRowCount() - 1 && row > 0) {

			CheckBox orderCheckBox = (CheckBox) flexTable.getWidget(row, 0);
			orderCheckBox.setValue(value);

			TextBox nameTextBox = (TextBox) flexTable.getWidget(row, 1);
			nameTextBox.setReadOnly(!value);

			ListBox ptypeListBox = (ListBox) flexTable.getWidget(row, 2);
			ptypeListBox.setEnabled(value);
			
			CheckBox isRequireCheckBox = (CheckBox) flexTable.getWidget(row, 3);
			isRequireCheckBox.setEnabled(value);

			CheckBox isSumaryCheckBox = (CheckBox) flexTable.getWidget(row, 4);
			isSumaryCheckBox.setEnabled(value);

			CheckBox isListCheckBox = (CheckBox) flexTable.getWidget(row, 5);
			isListCheckBox.setEnabled(value);

			CheckBox isMainCheckBox = (CheckBox) flexTable.getWidget(row, 6);
			isMainCheckBox.setEnabled(value);

			CheckBox isMultiCheckBox = (CheckBox) flexTable.getWidget(row, 7);
			isMultiCheckBox.setEnabled(value);

			CheckBox isReadonlyCheckBox = (CheckBox) flexTable.getWidget(row, 8);
			isReadonlyCheckBox.setEnabled(value);

			CheckBox isLinkedCheckBox = (CheckBox) flexTable.getWidget(row, 9);
			isLinkedCheckBox.setEnabled(value);

			TextBox desTextBox = (TextBox) flexTable.getWidget(row, 10);
			desTextBox.setReadOnly(!value);
		}
	}
	/*
	 * Create Otype CheckBox 
	 */
	private ListBox CreateObjectTypeListBox(String ptypeID){
		ListBox lb = new ListBox();
		lb.addItem(" -- Chọn Kiểu -- ","");
		int i = 1;
//		Window.alert(Integer.toString(listPType.size()));
		if (ptypeID != null) {
			ptypeID = ptypeID.trim();
			for (ObjectPropertyTypeDTO o : this.listPType) {
				String tempID = KeyFactory.keyToString(o.getId());
				tempID = tempID.trim();
//				Window.alert(o.getName() + " value = " + tempID);
				lb.addItem(o.getName().trim(), tempID);
				if (ptypeID.compareTo(tempID) == 0) {
					// Window.alert("So sanh (true):" + o.getName());
					lb.setSelectedIndex(i);
				}
				i++;
			}
		} else {
			for (ObjectPropertyTypeDTO o : this.listPType) {
				String tempID = KeyFactory.keyToString(o.getId());
				lb.addItem(o.getName().trim(), tempID.trim());
				i++;
			}
		}
		return lb;
	}
	/*
	 * Get Order CheckBox
	 */
	private CheckBox OrderCheckBox(int row, boolean value, boolean enable) {
		final CheckBox cb = new CheckBox();
		cb.setValue(value);
		cb.setEnabled(enable);
		return cb;
	}
	/*************************************************************************/
	private void initTableFirst() {
		flexTable.removeAllRows();
		/*
		 * Tên các cột
		 */
		int i = 0;
//		Window.alert("Init Table First");
		for (final String columnName : listStringColumn) {
			flexTable.setHTML(0, i, "<center><b>" + columnName
					+ "</b></center>");
//			Window.alert(listStringColumn.get(i));
			i++;
		}
	}

	/*
	 * Add Row with Wiget
	 */
	
	private int addRow(
			int row,
			Widget nameTextbox, 
			Widget ptypeListBox, 
			Widget isRequireCheckBox,
			Widget isSumaryCheckBox,
			Widget isListCheckBox,
			Widget isMainCheckBox,
			Widget isMultiCheckBox,
			Widget isReadonlyCheckBox,
			Widget isLinkedCheckBox,
			Widget desTextBox
			) {
		if(row == 0)
			row = flexTable.getRowCount();
		CheckBox sttCheckbox = OrderCheckBox(row, false, true);
		flexTable.setWidget(row, 0, sttCheckbox);
		flexTable.setWidget(row, 1, nameTextbox);
		flexTable.setWidget(row, 2, ptypeListBox);
		flexTable.setWidget(row, 3, isRequireCheckBox);
		flexTable.setWidget(row, 4, isSumaryCheckBox);
		flexTable.setWidget(row, 5, isListCheckBox);
		flexTable.setWidget(row, 6, isMainCheckBox);
		flexTable.setWidget(row, 7, isMultiCheckBox);
		flexTable.setWidget(row, 8, isReadonlyCheckBox);
		flexTable.setWidget(row, 9, isLinkedCheckBox);
		flexTable.setWidget(row, 10, desTextBox);
		setRowEnable(row, false);
		return row;
	}

	/*
	 * Add Row with data
	 */

	private int addRow(
			int row,
			String name,
			String ptype,
			boolean isRequire,
			boolean isSumary, 
			boolean isList, 
			boolean isMain, 
			boolean isMulti, 
			boolean isReadonly,
			boolean isLinked,
			String des
			) {
		if(row==0)
			row = flexTable.getRowCount();

		CheckBox sttCheckbox = OrderCheckBox(row, false, true);
		flexTable.setWidget(row, 0, sttCheckbox);

		TextBox nameTextBox = new TextBox();
		nameTextBox.setValue(name);
		flexTable.setWidget(row, 1, nameTextBox);
		
		ListBox ptypeListBox = CreateObjectTypeListBox(ptype);
		flexTable.setWidget(row, 2, ptypeListBox);

		CheckBox isRequireCheckBox = new CheckBox();
		isRequireCheckBox.setValue(isRequire);
		flexTable.setWidget(row, 3, isRequireCheckBox);

		CheckBox isSumaryCheckBox = new CheckBox();
		isSumaryCheckBox.setValue(isSumary);
		flexTable.setWidget(row, 4, isSumaryCheckBox);

		CheckBox isListCheckBox = new CheckBox();
		isListCheckBox.setValue(isList);
		flexTable.setWidget(row, 5, isListCheckBox);

		CheckBox isMainCheckBox = new CheckBox();
		isMainCheckBox.setValue(isMain);
		flexTable.setWidget(row, 6, isMainCheckBox);
		
		CheckBox isMultiCheckBox = new CheckBox();
		isMultiCheckBox.setValue(isMulti);
		flexTable.setWidget(row, 7, isMultiCheckBox);
		
		CheckBox isReadonlyCheckBox = new CheckBox();
		isReadonlyCheckBox.setValue(isReadonly);
		flexTable.setWidget(row, 8, isReadonlyCheckBox);
		
		CheckBox isLinkedCheckBox = new CheckBox();
		isLinkedCheckBox.setValue(isLinked);
		flexTable.setWidget(row, 9, isLinkedCheckBox);
		
		TextBox desTextBox = new TextBox();
		desTextBox.setValue(des);
		flexTable.setWidget(row, 10, desTextBox);
		
		setRowEnable(row, false);

		return row;
	}

	/*
	 * Add Row Empty
	 */
	private int addRow() {
		ObjectPropertyDTO o = new ObjectPropertyDTO();
		listRow.add(o);
		int row = addRow(
				0,
				new TextBox(), 
				CreateObjectTypeListBox(null),
				new CheckBox(), 
				new CheckBox(), 
				new CheckBox(), 
				new CheckBox(), 
				new CheckBox(), 
				new CheckBox(), 
				new CheckBox(), 
				new TextBox());
		setRowEnable(row, false);
		return row;
	}

	/*
	 * Remove selected Row
	 */
	private void removeRow() {
		if (rowSelectedID > 0 && rowSelectedID < flexTable.getRowCount()) {
			flexTable.removeRow(rowSelectedID);
			int remvIndex = Helper.getIndexByRow(rowSelectedID, listRow.size());
			if(remvIndex!=-1){
				listRow.remove(remvIndex);
			}
			rowSelectedID = -1;
		} else
			Window.alert("Chọn hàng cần xóa!");
	}

	/*
	 * Update all rows
	 */
	private void updateRow() {
//		Window.alert("updateRow");
//		Window.alert("ListRow" + listRow.size());
		for (int index = 0; index < listRow.size() ; index++) {
			int row = Helper.getRowByIndex(index, flexTable.getRowCount());

			TextBox nameTextBox = (TextBox) flexTable.getWidget(row, 1);
			ListBox ptypeListBox = (ListBox) flexTable.getWidget(row, 2);
			CheckBox isRequireCheckBox = (CheckBox) flexTable.getWidget(row, 3);
			CheckBox isSumaryCheckBox = (CheckBox) flexTable.getWidget(row, 4);
			CheckBox isListCheckBox = (CheckBox) flexTable.getWidget(row, 5);
			CheckBox isMainCheckBox = (CheckBox) flexTable.getWidget(row, 6);
			CheckBox isMultiCheckBox = (CheckBox) flexTable.getWidget(row, 7);
			CheckBox isReadonlyCheckBox = (CheckBox) flexTable.getWidget(row, 8);
			CheckBox isLinkedCheckBox = (CheckBox) flexTable.getWidget(row, 9);
			TextBox desTextBox = (TextBox) flexTable.getWidget(row, 10);
			Key objecttype = currentObjectTypeDTO.getId();
			
//			Window.alert("Key Get tu ds: " + ptypeListBox.getValue(ptypeListBox.getSelectedIndex()).trim());
			
			listRow.get(index).setName(nameTextBox.getValue());
			listRow.get(index).setOptype(ptypeListBox.getValue(ptypeListBox.getSelectedIndex()).trim());
			listRow.get(index).setRequire(isRequireCheckBox.getValue());
			listRow.get(index).setSummary(isSumaryCheckBox.getValue());
			listRow.get(index).setList(isListCheckBox.getValue());
			listRow.get(index).setMain(isMainCheckBox.getValue());
			listRow.get(index).setMulti(isMultiCheckBox.getValue());
			listRow.get(index).setReadonly(isReadonlyCheckBox.getValue());
			listRow.get(index).setLinked(isLinkedCheckBox.getValue());
			listRow.get(index).setDescribe(desTextBox.getValue());
			listRow.get(index).setObjecttype((KeyFactory.keyToString(objecttype)).trim());
			listRow.get(index).setWeight(index);
		}
		
		if (flexTable.getRowCount() - 1 > listRow.size()) {
			for (int row = listRow.size()+1; row < flexTable
					.getRowCount(); row++) {
				TextBox nameTextBox = (TextBox) flexTable.getWidget(row, 1);
				ListBox ptypeListBox = (ListBox) flexTable.getWidget(row, 2);
				CheckBox isRequireCheckBox = (CheckBox) flexTable.getWidget(row, 3);
				CheckBox isSumaryCheckBox = (CheckBox) flexTable.getWidget(row, 4);
				CheckBox isListCheckBox = (CheckBox) flexTable.getWidget(row, 5);
				CheckBox isMainCheckBox = (CheckBox) flexTable.getWidget(row, 6);
				CheckBox isMultiCheckBox = (CheckBox) flexTable.getWidget(row, 7);
				CheckBox isReadonlyCheckBox = (CheckBox) flexTable.getWidget(row, 8);
				CheckBox isLinkedCheckBox = (CheckBox) flexTable.getWidget(row, 9);
				TextBox desTextBox = (TextBox) flexTable.getWidget(row, 10);
				Key objecttype = currentObjectTypeDTO.getId();
				ObjectPropertyDTO o = new ObjectPropertyDTO(
						null, 
						nameTextBox.getValue(), 
						isSumaryCheckBox.getValue(), 
						isListCheckBox.getValue(), 
						isMainCheckBox.getValue(), 
						Helper.getIndexByRow(row, listRow.size()),
						isRequireCheckBox.getValue(), 
						desTextBox.getValue(),
						ptypeListBox.getValue(ptypeListBox.getSelectedIndex()),
						(KeyFactory.keyToString(objecttype)).trim(),
						isReadonlyCheckBox.getValue(),
						isLinkedCheckBox.getValue(),
						isMultiCheckBox.getValue()
						);
				listRow.add(o);
//				Window.alert("Moi tao " + o.getName() + " " + (KeyFactory.keyToString(objecttype)).trim() + " Describe: " + o.getDescribe());
			}
		}
	}
	private void upRow() {
		if (rowSelectedID > 1 && rowSelectedID < flexTable.getRowCount()) {
			int index = Helper.getIndexByRow(rowSelectedID, listRow.size());
			if(index>0){
				
				ObjectPropertyDTO op = listRow.get(index);
				listRow.remove(index);
				listRow.add(index-1, op);
			}
			
			int rowNew = flexTable.insertRow(rowSelectedID-1);
			int rowOld = rowSelectedID + 1;
			for(int i=0;i<listStringColumn.size();i++){
				flexTable.setWidget(rowNew, i, flexTable.getWidget(rowOld, i));
			}
			flexTable.removeRow(rowOld);
			rowSelectedID = rowNew;
			setRowEnable(rowSelectedID, true);
			renderClickedRow();
		} else
			Window.alert("Chọn hàng đưa lên!");

	}
	private void downRow() {
		if (rowSelectedID > 0 && rowSelectedID < flexTable.getRowCount()-1) {
			int index = Helper.getIndexByRow(rowSelectedID, listRow.size());
			if(index<listRow.size()-1){
				
				ObjectPropertyDTO op = listRow.get(index);
				listRow.remove(index);
				listRow.add(index+1, op);
			}
			
			int rowNew = flexTable.insertRow(rowSelectedID+2);
			int rowOld = rowSelectedID;
			for(int i=0;i<listStringColumn.size();i++){
				flexTable.setWidget(rowNew, i, flexTable.getWidget(rowOld, i));
			}
			flexTable.removeRow(rowOld);
			rowSelectedID = rowNew-1;
			setRowEnable(rowSelectedID, true);
			renderClickedRow();
		} else
			Window.alert("Chọn hàng cần đưa xuống!");
	}

	/********************************************************************************/
	
	/*
	 * Event
	 */
	
	@UiHandler("btAdd")
	void onBtAddClick(ClickEvent event) {
		addRow();
	}
	@UiHandler("btDel")
	void onBtDelClick(ClickEvent event) {
		removeRow();
	}
	@UiHandler("btUpdate")
	void onBtUpdateClick(ClickEvent event) {
//		Window.alert("btUpdate");
		updateRow();
	}
	@UiHandler("btUp")
	void onBtUpClick(ClickEvent event) {
		upRow();
	}
	@UiHandler("btDown")
	void onBtDownClick(ClickEvent event) {
		downRow();
	}



	/********************************************************************************/
	
	@Override
	public Button getUpdateButton() {
		return btUpdate;
	}

	@Override
	public ArrayList<ObjectPropertyDTO> getListRow() {
		return (ArrayList<ObjectPropertyDTO>) listRow;
	}

	@Override
	public boolean setListRow(List<ObjectPropertyDTO> listRow) {
		this.listRow = listRow;
		return true;
	}

	@Override
	public ObjectTypeDTO getCurrentObjectTypeDTO() {
		return currentObjectTypeDTO;
	}

	@Override
	public void setCurrentObjectTypeDTO(ObjectTypeDTO o) {
		currentObjectTypeDTO = o;
	}

	@Override
	public void render() {
//		Window.alert("render");
		rowSelectedID = -1;
		initTableFirst();
		for (final ObjectPropertyDTO o : this.listRow) {
			addRow(
					0,
					o.getName(), 
					o.getOptype(),
					o.getRequire(), 
					o.getSummary(), 
					o.getList(), 
					o.getMain(), 
					o.getMulti(),
					o.getReadonly(),
					o.getLinked(),
					o.getDescribe()
					);
		}
	}
	@Override
	public	Widget asWidget(){
		return this;
	}

	@Override
	public ArrayList<ObjectPropertyTypeDTO> getListPType() {
		return (ArrayList<ObjectPropertyTypeDTO>) listPType;
	}

	@Override
	public boolean setListPType(List<ObjectPropertyTypeDTO> listPType) {
		this.listPType = listPType;
		return true;
	}
}
